正規表達式自己有test和exec二個方法,搭配字串的match,search, replace等方法,可以有強大的功能。
<div class="foo bar"></div>
<div class="bar foo"></div>
<div></div>
<span class="foo bar baz"></span>
<script>
	function findClassInElements(className, type) {
		const elems = document.getElementsByTagName(type || "*");
		const regex = new RegExp("(^|\\s)" + className + "\\s|$");
		const results = [];
		for (let i = 0; i < elems.length; i++) {
			if (regex.test(elems[i].className)) {
				results.push(elems[i]);
			}
		}
		return results;
	}
	console.log(findClassInElements("foo", "div").length); // 2
	console.log(findClassInElements("foo", "span").length); // 1
	console.log(findClassInElements("foo").length); // 3
</script>
這裡我們自建一個 HTML 搜尋器,可以找出頁面上有指定 class name 的 HTML 元素。
我們先用getElementsByTagName抓取指定的 HTML 標籤,如果沒有這個參數的話就抓頁面上全部元素,存在elems的陣列裡。
然後我們根據參數裡的 class name 建立正規表達式。Class name 是寫在 HTML 元素的class屬性裡,但是我們不能確定它的順序,不過可以歸納出這些規則:
事實上只是 class name 前後有沒有空格的問題,所以正規表達式就是"(^|\\s)" + className + "\\s|$"。又因為 class name 要等到函式被呼叫時才會知道,正規表達式就不能用實質方式建立,必須用new RegExp()動態產生,此時規則要以字串方式代入。我們又用了\s代表空白符號,反斜線在字串裡出現代表要 escape 緊跟在後的字元,但是我們要保留\s當中的反斜線,所以要在前面加上反斜線來 escape 它。這是用字串建立正規表達式比較麻煩的地方。
接著建一個空陣列來保管等一下匹配到的結果。
我們將elems陣列裡的 HTML 元素丟進迴圈裡,檢查每個元素的className是否匹配我們的正規表達式。在這裡使用正規表達式的test方法,如果有匹配到會回傳true,反之回傳false。將有匹配到的元素存進results陣列裡。